package com.xdb.sqlparser.dialect.oracle.parser;

import com.xdb.sqlparser.ast.SQLExpr;
import com.xdb.sqlparser.ast.statement.SQLTableSource;
import com.xdb.sqlparser.dialect.oracle.ast.statement.OracleUpdateStatement;
import com.xdb.sqlparser.dialect.sql99.parser.SQL99StatementParser;
import com.xdb.sqlparser.exception.ParserException;
import com.xdb.sqlparser.parser.SQLLexer;
import com.xdb.sqlparser.parser.SQLToken;

public class OracleUpdateParser extends SQL99StatementParser {

	public OracleUpdateParser(String sql) {
		super(new OracleExprParser(sql));
	}

	public OracleUpdateParser(SQLLexer lexer) {
		super(new OracleExprParser(lexer));
	}

	public OracleUpdateStatement parseUpdateStatement() {
		OracleUpdateStatement update = new OracleUpdateStatement();

		if (lexer.token() == SQLToken.UPDATE) {
			lexer.nextToken();

			parseHints(update);

			if (identifierEquals("ONLY")) {
				update.setOnly(true);
			}

			SQLTableSource tableSource = this.exprParser.createSelectParser().parseTableSource();
			update.setTableSource(tableSource);

			if ((update.getAlias() == null) || (update.getAlias().length() == 0)) {
				update.setAlias(as());
			}
		}

		parseUpdateSet(update);

		parseWhere(update);

		parseReturn(update);

		parseErrorLoging(update);

		return update;
	}

	private void parseErrorLoging(OracleUpdateStatement update) {
		if (identifierEquals("LOG")) {
			throw new ParserException("TODO");
		}
	}

	private void parseReturn(OracleUpdateStatement update) {
		if (identifierEquals("RETURN") || lexer.token() == SQLToken.RETURNING) {
			lexer.nextToken();

			for (;;) {
				SQLExpr item = this.exprParser.expr();
				update.getReturning().add(item);

				if (lexer.token() == SQLToken.COMMA) {
					lexer.nextToken();
					continue;
				}

				break;
			}

			accept(SQLToken.INTO);

			for (;;) {
				SQLExpr item = this.exprParser.expr();
				update.getReturningInto().add(item);

				if (lexer.token() == SQLToken.COMMA) {
					lexer.nextToken();
					continue;
				}

				break;
			}
		}
	}

	private void parseHints(OracleUpdateStatement update) {
		this.exprParser.parseHints(update.getHints());
	}

	private void parseWhere(OracleUpdateStatement update) {
		if (lexer.token() == (SQLToken.WHERE)) {
			lexer.nextToken();
			update.setWhere(this.exprParser.expr());
		}
	}

}
